const std = @import("std");
const Allocator = std.mem.Allocator;

/// Virtual Actor - 受 Orleans 启发的虚拟角色系统
/// 核心特性：
/// 1. 按需激活 - Actor 在首次访问时自动创建
/// 2. 自动失活 - 空闲超时后自动回收
/// 3. 状态持久化 - 失活时保存，激活时恢复
/// 4. 位置透明 - 调用者无需知道 Actor 是否存在
/// 5. 单线程执行 - 每个 Actor 串行处理消息

/// Actor ID - 唯一标识一个 Virtual Actor
pub const ActorId = struct {
    type_name: []const u8,
    id: []const u8,
    
    pub fn hash(self: ActorId) u64 {
        var hasher = std.hash.Wyhash.init(0);
        hasher.update(self.type_name);
        hasher.update(self.id);
        return hasher.final();
    }
    
    pub fn eql(self: ActorId, other: ActorId) bool {
        return std.mem.eql(u8, self.type_name, other.type_name) and
               std.mem.eql(u8, self.id, other.id);
    }
};

/// Actor 生命周期状态
pub const ActorLifecycle = enum {
    uninitialized,  // 未初始化
    activating,     // 正在激活
    active,         // 活跃
    deactivating,   // 正在失活
    deactivated,    // 已失活
};

/// Virtual Actor 基类
pub fn VirtualActor(comptime StateType: type) type {
    return struct {
        const Self = @This();
        
        allocator: Allocator,
        id: []const u8,
        state: StateType,
        lifecycle: ActorLifecycle,
        last_access: i64,
        mutex: std.Thread.Mutex,
        
        /// 激活 Actor（从存储加载状态）
        pub fn activate(self: *Self, storage: anytype) !void {
            self.lifecycle = .activating;
            defer self.lifecycle = .active;
            
            // 尝试从存储加载状态
            if (storage.load(self.id, StateType)) |loaded_state| {
                self.state = loaded_state;
            } else |_| {
                // 首次创建，使用默认状态
            }
            
            self.last_access = std.time.timestamp();
        }
        
        /// 失活 Actor（保存状态到存储）
        pub fn deactivate(self: *Self, storage: anytype) !void {
            self.lifecycle = .deactivating;
            defer self.lifecycle = .deactivated;
            
            // 保存状态到存储
            try storage.save(self.id, self.state);
        }
        
        /// 更新最后访问时间
        pub fn touch(self: *Self) void {
            self.last_access = std.time.timestamp();
        }
        
        /// 检查是否空闲超时
        pub fn isIdle(self: *Self, timeout_seconds: i64) bool {
            const now = std.time.timestamp();
            return (now - self.last_access) > timeout_seconds;
        }
    };
}

/// Actor 注册表 - 管理所有活跃的 Virtual Actor
pub const ActorRegistry = struct {
    allocator: Allocator,
    actors: std.AutoHashMap(u64, *anyopaque),
    mutex: std.Thread.Mutex,
    idle_timeout: i64,
    
    pub fn init(allocator: Allocator, idle_timeout: i64) ActorRegistry {
        return .{
            .allocator = allocator,
            .actors = std.AutoHashMap(u64, *anyopaque).init(allocator),
            .mutex = .{},
            .idle_timeout = idle_timeout,
        };
    }
    
    pub fn deinit(self: *ActorRegistry) void {
        self.actors.deinit();
    }
    
    /// 获取或创建 Actor
    pub fn getOrCreate(
        self: *ActorRegistry,
        comptime ActorType: type,
        actor_id: ActorId,
        storage: anytype,
    ) !*ActorType {
        const hash_value = actor_id.hash();
        
        self.mutex.lock();
        defer self.mutex.unlock();
        
        // 检查是否已存在
        if (self.actors.get(hash_value)) |ptr| {
            const actor = @as(*ActorType, @ptrCast(@alignCast(ptr)));
            actor.touch();
            return actor;
        }
        
        // 创建新 Actor
        const actor = try self.allocator.create(ActorType);
        errdefer self.allocator.destroy(actor);
        
        actor.* = .{
            .allocator = self.allocator,
            .id = try self.allocator.dupe(u8, actor_id.id),
            .state = undefined,
            .lifecycle = .uninitialized,
            .last_access = std.time.timestamp(),
            .mutex = .{},
        };
        
        // 激活 Actor
        try actor.activate(storage);
        
        // 注册到注册表
        try self.actors.put(hash_value, actor);
        
        return actor;
    }
    
    /// 失活空闲的 Actor
    pub fn deactivateIdle(self: *ActorRegistry, storage: anytype) !void {
        self.mutex.lock();
        defer self.mutex.unlock();
        
        var to_remove = std.ArrayList(u64).init(self.allocator);
        defer to_remove.deinit();
        
        var iter = self.actors.iterator();
        while (iter.next()) |entry| {
            const actor = @as(*VirtualActor(void), @ptrCast(@alignCast(entry.value_ptr.*)));
            
            if (actor.isIdle(self.idle_timeout)) {
                // 失活并保存状态
                try actor.deactivate(storage);
                try to_remove.append(entry.key_ptr.*);
            }
        }
        
        // 移除失活的 Actor
        for (to_remove.items) |hash_value| {
            if (self.actors.fetchRemove(hash_value)) |kv| {
                self.allocator.destroy(@as(*anyopaque, @ptrCast(kv.value)));
            }
        }
    }
};

/// 状态存储接口
pub fn StateStorage(comptime StateType: type) type {
    return struct {
        const Self = @This();
        
        saveFn: *const fn(*Self, []const u8, StateType) anyerror!void,
        loadFn: *const fn(*Self, []const u8) anyerror!StateType,
        deleteFn: *const fn(*Self, []const u8) anyerror!void,
        
        pub fn save(self: *Self, id: []const u8, state: StateType) !void {
            return self.saveFn(self, id, state);
        }
        
        pub fn load(self: *Self, id: []const u8) !StateType {
            return self.loadFn(self, id);
        }
        
        pub fn delete(self: *Self, id: []const u8) !void {
            return self.deleteFn(self, id);
        }
    };
}

/// 内存存储实现（用于测试）
pub fn MemoryStorage(comptime StateType: type) type {
    return struct {
        const Self = @This();
        
        allocator: Allocator,
        data: std.StringHashMap(StateType),
        
        pub fn init(allocator: Allocator) Self {
            return .{
                .allocator = allocator,
                .data = std.StringHashMap(StateType).init(allocator),
            };
        }
        
        pub fn deinit(self: *Self) void {
            self.data.deinit();
        }
        
        pub fn save(self: *Self, id: []const u8, state: StateType) !void {
            const key = try self.allocator.dupe(u8, id);
            try self.data.put(key, state);
        }
        
        pub fn load(self: *Self, id: []const u8) !StateType {
            return self.data.get(id) orelse error.NotFound;
        }
        
        pub fn delete(self: *Self, id: []const u8) !void {
            _ = self.data.remove(id);
        }
    };
}

test "Virtual Actor 基础功能" {
    const testing = std.testing;
    
    const UserState = struct {
        balance: f64 = 0.0,
    };
    
    const UserActor = VirtualActor(UserState);
    
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();
    
    var storage = MemoryStorage(UserState).init(allocator);
    defer storage.deinit();
    
    var registry = ActorRegistry.init(allocator, 300);
    defer registry.deinit();
    
    // 获取 Actor（自动创建和激活）
    const actor_id = ActorId{ .type_name = "UserActor", .id = "user_001" };
    const actor = try registry.getOrCreate(UserActor, actor_id, &storage);
    
    try testing.expect(actor.lifecycle == .active);
    try testing.expect(actor.state.balance == 0.0);
    
    // 修改状态
    actor.state.balance = 100.0;
    
    // 失活（保存状态）
    try actor.deactivate(&storage);
    
    // 重新激活（加载状态）
    try actor.activate(&storage);
    try testing.expect(actor.state.balance == 100.0);
}
